/****************************************************************************
 * Copyright 2009 Huascar A. Sanchez                                        *
 *                                                                          *
 * Licensed under the Apache License, Version 2.0 (the "License");          *
 * you may not use this file except in compliance with the License.         *
 * You may obtain a copy of the License at                                  *
 *                                                                          *
 *     http://www.apache.org/licenses/LICENSE-2.0                           *
 *                                                                          *
 * Unless required by applicable law or agreed to in writing, software      *
 * distributed under the License is distributed on an "AS IS" BASIS,        *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
 * See the License for the specific language governing permissions and      *
 * limitations under the License.                                           *
 ****************************************************************************/
package com.gotobject.filter.builders;

import com.gotobject.filter.command.Command;
import com.gotobject.filter.predicate.Predicate;
import com.gotobject.filter.transformation.Transformation;

/**
 * @author huascar.sanchez@gmail.com (Huascar A. Sanchez)
 * @param <T> bound type.
 */
public interface FilteringBuilder <T> {
    /**
     * apply a transformation to the resulting subset of elements.
     * @param key
     *      transformation to be applied to filtered subset of
     *      a master collection..
     * @param <R>
     *      bound type.
     * @return
     *      an iterable object with bound type <R>
     */
    <R> Iterable<R> apply(Transformation<? super R> key);

    /**
     * play a closure on filtered elements.
     *
     * @param command
     *      a closure to be played on each filtered element.
     * @return
     *      an iterable object with bound type <T>. Source and returned object
     *      should agree (same object by equality).
     */
    Iterable<T> play(Command<? super T> command);

    /**
     * select all the elements that were substracted from the master collection
     * that was filtered.
     * @return
     *      a subset of master collection.
     */
    Iterable <T> select();

    /**
     * select a number of elements that were substraxted from a master collection.
     * @param number
     *      number of elements to be obtained from the returned subset.
     * @return
     *      a subset of a subset returned after filtering a master collection.
     */
    Iterable<T> select(int number);

    /**
     * out of all the elements substracted from the master collection, select only
     * the ones satisfy the <code>key</code> predicate.
     * @param key
     *      post predicate to be applied to the obtained subset.
     * @return
     *      a subset of master collection.
     */
    Iterable <T> select(Predicate<? super T> key);

    /**
     * skip a number of elements that were substraxted from a master collection.
     * @param n
     *      # of elements to be skipped.
     * @return
     *      subset of elements minus the elements that were skipped.
     */
    Iterable <T> skip(int n);

    /**
     * out of all the elements substracted from the master collection, skip only
     * the ones satisfy the <code>key</code> predicate.
     * @param key
     *      post predicate to be applied to the subset to be skipped.
     * @return
     *      a subset of master collection minus the elements that were skipped..
     */
    Iterable <T> skip(Predicate<? super T> key);
}
